package com.health.db.service.sm.impl;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import com.alipay.api.request.*;
import com.alipay.api.response.*;
import org.apache.log4j.Logger;

import net.sf.json.JSONObject;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.health.mapp.utils.DateUtils;
import com.health.pay.alipay.AlipayConfig;
import com.health.pay.alipay.AlipayCore;
import com.health.db.service.sm.IAlipayService;

public class AlipayServiceImpl implements IAlipayService {

    private static Logger logger = Logger.getLogger(AlipayServiceImpl.class);

    /**
     * 当交易发生之后一段时间内，由于买家或者卖家的原因需要退款时，卖家可以通过退款接口将支付款退还给买家，
     * 支付宝将在收到退款请求并且验证成功之后，按照退款规则将支付款按原路退到买家帐号上。 交易超过约定时间
     * （签约时设置的可退款时间）的订单无法进行退款 支付宝退款支持单笔交易分多次退款，多次退款需要提交原支
     * 付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交，要采用原来的退款单号。总退款金额不
     * 能超过用户实际支付金额
     * */
    /**
     * 支付宝统一收单交易退款接口
     *
     * @param out_trade_no   订单支付时传入的商户订单号,不能和 trade_no同时为空(特殊可选)
     * @param trade_no       支付宝交易号，和商户订单号不能同时为空(特殊可选)
     * @param refund_amount  需要退款的金额，该金额不能大于订单金额,单位为元，支持两位小数(必选)
     * @param refund_reason  退款的原因说明(可选)
     * @param out_request_no 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。(可选)
     * @param operator_id    商户的操作员编号(可选)
     * @param store_id       商户的门店编号(可选)
     * @param terminal_id    商户的终端编号(可选)
     */
    @Override
    public AlipayTradeRefundResponse refund(String out_trade_no,
                                            String trade_no, String refund_amount, String refund_reason,
                                            String out_request_no, String operator_id, String store_id,
                                            String terminal_id) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", out_trade_no);
        bizContent.put("trade_no", trade_no);
        bizContent.put("refund_amount", refund_amount);
        bizContent.put("refund_reason", refund_reason);
        bizContent.put("out_request_no", out_request_no);
        bizContent.put("operator_id", operator_id);
        bizContent.put("store_id", store_id);
        bizContent.put("terminal_id", terminal_id);
        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            // TODO Auto-generated catch block
            logger.error("refund", e);
        }
        return response;
    }

    /**
     * 该接口提供所有支付宝支付订单的查询，商户可以通过该接口主动查询订单状态，完成下一步的业务逻辑。
     * 需要调用查询接口的情况：
     * 当商户后台、网络、服务器等出现异常，商户系统最终未接收到支付通知；
     * 调用支付接口后，返回系统错误或未知交易状态情况； 调用alipay.trade.pay，返回INPROCESS的状态；
     * 调用alipay.trade.cancel之前，需确认支付状态；
     */
    @Override
    public AlipayTradeQueryResponse queryOrder(String outTradeNo, String tradeNo) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("trade_no", tradeNo);
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            // TODO Auto-generated catch block
            logger.error("queryOrder", e);
        }
        return response;
    }

    @Override
    public String applyPay(Map<String, String> param) throws Exception {
        // TODO Auto-generated method stub

        //"yyyy-MM-dd HH:mm:ss"
        String timestamp = DateUtils.currentDatetime();
        // 公共参数
        Map<String, String> map = new HashMap<String, String>();
        map.put("app_id", AlipayConfig.app_id);
        map.put("method", "alipay.trade.app.pay");
        map.put("format", "JSON");
        map.put("charset", "utf-8");
        map.put("sign_type", AlipayConfig.sign_type);
        map.put("timestamp", timestamp);
        map.put("version", "1.0");
        map.put("notify_url", AlipayConfig.notify_url);

        JSONObject bizcontentJson = JSONObject.fromObject(param);
        map.put("biz_content", bizcontentJson.toString());

        // 对未签名原始字符串进行签名
        String rsaSign = AlipaySignature.rsaSign(AlipaySignature.getSignContent(map), AlipayConfig.alipay_private_key, "utf-8", AlipayConfig.sign_type);

        Map<String, String> map4 = new HashMap<String, String>();


        map4.put("app_id", AlipayConfig.app_id);
        map4.put("method", "alipay.trade.app.pay");
        map4.put("format", "JSON");
        map4.put("charset", "utf-8");
        map4.put("sign_type", AlipayConfig.sign_type);
        map4.put("timestamp", URLEncoder.encode(timestamp,
                "UTF-8"));
        map4.put("version", "1.0");
        map4.put("notify_url", URLEncoder.encode(AlipayConfig.notify_url,
                "UTF-8"));
        // 最后对请求字符串的所有一级value（biz_content作为一个value）进行encode，编码格式按请求串中的charset为准，没传charset按UTF-8处理
        map4.put("biz_content", URLEncoder.encode(bizcontentJson.toString(),
                "UTF-8"));

        Map par = AlipayCore.paraFilter(map4); // 除去数组中的空值和签名参数
        String json4 = AlipayCore.createLinkString(map4); // 拼接后的字符串

        json4 = json4 + "&sign=" + URLEncoder.encode(rsaSign, "UTF-8");
        return json4;
    }

    @Override
    public String applyWapPay(String subject, String out_trade_no, String total_amount, String goods_type) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "UTF-8",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setNotifyUrl(AlipayConfig.notify_url);
        request.setReturnUrl(AlipayConfig.wap_return_url);
        JSONObject bizContent = new JSONObject();
        bizContent.put("subject", subject);
        bizContent.put("out_trade_no", out_trade_no);
        bizContent.put("total_amount", total_amount);
        bizContent.put("product_code", "QUICK_WAP_PAY");
        bizContent.put("goods_type", goods_type);
        request.setBizContent(bizContent.toString());
        String response = alipayClient.pageExecute(request).getBody();
        return response;
    }

    @Override
    public AlipayTradeCancelResponse cancel(String tradeNo, String outTradeNo) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", tradeNo);
        bizContent.put("trade_no", outTradeNo);
        request.setBizContent(bizContent.toString());
        AlipayTradeCancelResponse response = null;
        response = alipayClient.execute(request);
        return response;
    }

    @Override
    public AlipayTradeCloseResponse close(String tradeNo, String outTradeNo) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", tradeNo);
        bizContent.put("trade_no", outTradeNo);
        request.setBizContent(bizContent.toString());
        AlipayTradeCloseResponse response = null;
        response = alipayClient.execute(request);
        return response;
    }

    @Override
    public AlipayTradeCreateResponse create(String outTradeNo,
                                            String totalAmount, String subject, String body) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", outTradeNo);
        bizContent.put("total_amount", totalAmount);
        bizContent.put("subject", subject);
        bizContent.put("body", body);
        request.setBizContent(bizContent.toString());
        AlipayTradeCreateResponse response = null;
        response = alipayClient.execute(request);
        return response;
    }

    @Override
    public AlipayTradeFastpayRefundQueryResponse refundQuery(String tradeNo,
                                                             String outTradeNo, String outRequestNo) throws AlipayApiException {
        // TODO Auto-generated method stub
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", AlipayConfig.app_id,
                AlipayConfig.alipay_private_key, "json", "GBK",
                AlipayConfig.alipay_public_key, "RSA2");
        AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", tradeNo);
        bizContent.put("trade_no", outTradeNo);
        bizContent.put("out_request_no", outRequestNo);
        request.setBizContent(bizContent.toString());
        AlipayTradeFastpayRefundQueryResponse response = null;
        response = alipayClient.execute(request);
        return response;
    }


}
